﻿/*-----------------------------------------------------------------------
 * <copyright file="DynamicSort.cs" company="O-RID">
 *     Copyright (c)2010 O-RID Co.,Ltd.
 * </copyright>
 * <author>zhangjun</author>
 * <summary>       
 *              LINQ动态排序
 *              
 *          作成日：09/25/2010
 *</summary>
 *-----------------------------------------------------------------------
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Orid.Management.Statistics.OperatorUnitMangement.Common.DynamicLinq
{
    public static class DynamicSort
    {
        /// <summary>
        /// 组合要排序的 LAMBDA 字段
        /// </summary>
        /// <typeparam name="TSource">泛型的数据源</typeparam>
        /// <typeparam name="TResult">排序字段的类型.</typeparam>
        /// <param name="propertyOrFieldName">要排序的字段名.</param>
        /// <param name="isOrderDesc">Ture:降序  False:升序</param>
        /// <returns></returns>
        /// <value>09/25/2010 Add</value>
        private static Expression<Func<TSource, TResult>> GetPropertyOrFieldByName<TSource, TResult>(string propertyOrFieldName, bool isOrderDesc)
        {   
            //表达式的泛型类Expression<T>,Lambda表达式树
            //ParameterExpression,就是一个方法中的参数,例如 search(string key),key可以看成是一个参数表达式。
            //创建一个参数c
            ParameterExpression item = System.Linq.Expressions.Expression.Parameter(typeof(TSource), "classObject");

            //字段或属性表达式：MemberExpression，例如str.Length。Expression.Property(pe, typeof(string).GetProperty("Length"));
            ///classObject.propertyOrFieldName
            MemberExpression prop = LambdaExpression.PropertyOrField(item, propertyOrFieldName);

            var expr = System.Linq.Expressions.Expression.Lambda<Func<TSource, TResult>>(prop, new ParameterExpression[] { item });

            expr.Compile();

            return expr;

        }

        /// <summary>
        /// 排序(对单个字段)
        /// </summary>
        /// <typeparam name="T">泛型的数据源</typeparam>
        /// <param name="sortData">排序数据源</param>
        /// <param name="sortFile">排序字段</param>
        /// <param name="isDesc">Ture:降序  False:升序</param>
        /// <returns></returns>
        public static List<T> LinqOrderBy<T>(List<T> sortData, string sortFile, bool isDesc)
        {

            IQueryable query = sortData.AsQueryable();
            
            //标准的Lambda表达式
            //Expression<Func<OperatorRolesData, string>> lambda = x => x.Unit;

            LambdaExpression expression = GetPropertyOrFieldByName<T,string>(sortFile, isDesc);

            Type[] typeArgs = new Type[] { query.ElementType, expression.Body.Type };

            IQueryable<T> orderQuery;
            
            //降序
            if (isDesc)
            {
                var mc = System.Linq.Expressions.Expression.Call(typeof(Queryable), "OrderByDescending", typeArgs, query.Expression, expression);
                orderQuery = query.Provider.CreateQuery<T>(mc);
            }
            else 
            {
                var mc = System.Linq.Expressions.Expression.Call(typeof(Queryable), "OrderBy", typeArgs, query.Expression, expression);
                orderQuery = query.Provider.CreateQuery<T>(mc);
            }

            return orderQuery.ToList<T>();

        }
    }
}
